﻿//===================================================================================
// Microsoft Developer & Platform Evangelism
//=================================================================================== 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.


namespace Infrastructure.CrossCutting.SeedWork.Adapter
{
    /// <summary>
    ///     Base contract for map dto to aggregate or aggregate to dto.
    ///     <remarks>
    ///         This is a  contract for work with "auto" mappers ( automapper,emitmapper,valueinjecter...)
    ///         or adhoc mappers
    ///     </remarks>
    /// </summary>
    public interface ITypeAdapter
    {
        /// <summary>
        ///     Adapt a source object to an instance of type <paramref name="TTarget" />
        /// </summary>
        /// <typeparam name="TSource">Type of source item</typeparam>
        /// <typeparam name="TTarget">Type of target item</typeparam>
        /// <param name="source">Instance to adapt</param>
        /// <returns><paramref name="source" /> mapped to <typeparamref name="TTarget" /></returns>
        TTarget Adapt<TSource, TTarget>(TSource source)
            where TTarget : class, new()
            where TSource : class;

        /// <summary>
        ///     use source values to chage target  values
        /// </summary>
        /// <typeparam name="TSource">Type of source item</typeparam>
        /// <typeparam name="TTarget">Type of target item</typeparam>
        /// <param name="source">Instance to adapt</param>
        /// <param name="target"></param>
        /// <returns><paramref name="source" /> mapped to <typeparamref name="TTarget" /></returns>
        TTarget Convert<TSource, TTarget>(TSource source, TTarget target)
            where TTarget : class
            where TSource : class;

        /// <summary>
        ///     Adapt a source object to an instance of type <paramref name="TTarget" />
        /// </summary>
        /// <typeparam name="TSource">Type of source item</typeparam>
        /// <typeparam name="TTarget">Type of target item</typeparam>
        /// <param name="source">Instance to adapt</param>
        /// <param name="target"></param>
        /// <param name="config"></param>
        /// <returns><paramref name="source" /> mapped to <typeparamref name="TTarget" /></returns>
        TTarget Convert<TSource, TTarget>(TSource source, TTarget target, object config)
            where TTarget : class
            where TSource : class;

        /// <summary>
        ///     use source values to chage target  values with config
        /// </summary>
        /// <typeparam name="TSource">Type of source item</typeparam>
        /// <typeparam name="TTarget">Type of target item</typeparam>
        /// <param name="source">Instance to adapt</param>
        /// <param name="config"></param>
        /// <returns><paramref name="source" /> mapped to <typeparamref name="TTarget" /></returns>
        TTarget Convert<TSource, TTarget>(TSource source, object config)
            where TTarget : class, new()
            where TSource : class;
    }
}